box: Use CSS nodes instead of widget paths
authorBenjamin Otte <otte@redhat.com>
Mon, 9 Feb 2015 21:51:28 +0000 (22:51 +0100)
committerBenjamin Otte <otte@redhat.com>
Wed, 18 Mar 2015 14:23:31 +0000 (15:23 +0100)
This is a very simple patch that causes a bunch of overhead. But it
works.

gtk/gtkbox.c
gtk/gtkcssnode.c
gtk/gtkcssnodeprivate.h
gtk/gtkcsswidgetnode.c

index 818e4d1a97f4859bf9b58c4b7e032e75f5be30cc..3a2fb5ac35489a07419d6960a4f03f96fd0f28e9 100644 (file)
@@ -77,6 +77,7 @@
 
 #include "gtkbox.h"
 #include "gtkboxprivate.h"
+#include "gtkcssnodeprivate.h"
 #include "gtkintl.h"
 #include "gtkorientable.h"
 #include "gtkorientableprivate.h"
@@ -1434,17 +1435,25 @@ gtk_box_buildable_init (GtkBuildableIface *iface)
 }
 
 static void
-gtk_box_invalidate_order_foreach (GtkWidget *widget)
+gtk_box_invalidate_order_foreach (GtkWidget *widget,
+                                  gpointer   prev)
 {
-  _gtk_widget_invalidate_style_context (widget, GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_SIBLING_POSITION);
+  GtkCssNode **previous = prev;
+  GtkCssNode *cur = gtk_widget_get_css_node (widget);
+
+  if (*previous)
+    gtk_css_node_set_after (cur, *previous);
+
+  *previous = cur;
 }
 
 static void
 gtk_box_invalidate_order (GtkBox *box)
 {
+  GtkCssNode *previous = NULL;
   gtk_container_foreach (GTK_CONTAINER (box),
-                         (GtkCallback) gtk_box_invalidate_order_foreach,
-                         NULL);
+                         gtk_box_invalidate_order_foreach,
+                         &previous);
 }
 
 static void
@@ -1490,8 +1499,8 @@ gtk_box_pack (GtkBox      *box,
 
   gtk_widget_freeze_child_notify (child);
 
-  gtk_box_invalidate_order (box);
   gtk_widget_set_parent (child, GTK_WIDGET (box));
+  gtk_box_invalidate_order (box);
 
   g_signal_connect (child, "notify::visible",
                     G_CALLBACK (box_child_visibility_notify_cb), box);
index 92b165dfa3142afd677a78f3b8fcdb8b65d962e9..402aa3366df0e65394d1bed5e324dc8bc2a542a9 100644 (file)
@@ -473,6 +473,30 @@ gtk_css_node_set_parent (GtkCssNode *node,
   gtk_css_node_reposition (node, parent, parent ? parent->last_child : NULL);
 }
 
+void
+gtk_css_node_set_after (GtkCssNode *cssnode,
+                        GtkCssNode *previous_sibling)
+{
+  if (cssnode->previous_sibling == previous_sibling)
+    return;
+
+  gtk_css_node_reposition (cssnode,
+                           previous_sibling->parent,
+                           previous_sibling);
+}
+
+void
+gtk_css_node_set_before (GtkCssNode *cssnode,
+                         GtkCssNode *next_sibling)
+{
+  if (cssnode->next_sibling == next_sibling)
+    return;
+
+  gtk_css_node_reposition (cssnode,
+                           next_sibling->parent,
+                           next_sibling->previous_sibling);
+}
+
 GtkCssNode *
 gtk_css_node_get_parent (GtkCssNode *cssnode)
 {
index b1339b0b9c239f9e98af83f3a3319b5b95b0b09c..3c6abfdb23687b7037fca2245db47cb46eb94f7b 100644 (file)
@@ -78,6 +78,10 @@ GType                   gtk_css_node_get_type           (void) G_GNUC_CONST;
 
 void                    gtk_css_node_set_parent         (GtkCssNode            *cssnode,
                                                          GtkCssNode            *parent);
+void                    gtk_css_node_set_after          (GtkCssNode            *cssnode,
+                                                         GtkCssNode            *previous_sibling);
+void                    gtk_css_node_set_before         (GtkCssNode            *cssnode,
+                                                         GtkCssNode            *next_sibling);
 GtkCssNode *            gtk_css_node_get_parent         (GtkCssNode            *cssnode);
 GtkCssNode *            gtk_css_node_get_first_child    (GtkCssNode            *cssnode);
 GtkCssNode *            gtk_css_node_get_last_child     (GtkCssNode            *cssnode);
index e18cdc3127bbbe816113b45a920e8c742978ab86..5c89a9812478493b1c27a0e585f88caf2fab1aab 100644 (file)
@@ -24,6 +24,8 @@
 #include "gtkprivate.h"
 #include "gtkstylecontextprivate.h"
 #include "gtkwidgetprivate.h"
+/* widgets for special casing go here */
+#include "gtkbox.h"
 
 /* When these change we do a full restyling. Otherwise we try to figure out
  * if we need to change things. */
@@ -173,7 +175,7 @@ typedef GtkWidgetPath * (* GetPathForChildFunc) (GtkContainer *, GtkWidget *);
 static gboolean
 widget_needs_widget_path (GtkWidget *widget)
 {
-  static GetPathForChildFunc funcs[1];
+  static GetPathForChildFunc funcs[2];
   GtkWidget *parent;
   GetPathForChildFunc parent_func;
   guint i;
@@ -182,6 +184,7 @@ widget_needs_widget_path (GtkWidget *widget)
     {
       i = 0;
       funcs[i++] = GTK_CONTAINER_CLASS (g_type_class_ref (GTK_TYPE_CONTAINER))->get_path_for_child;
+      funcs[i++] = GTK_CONTAINER_CLASS (g_type_class_ref (GTK_TYPE_BOX))->get_path_for_child;
 
       g_assert (i == G_N_ELEMENTS (funcs));
     }